#include "WIFI_SMARTCONFIG.h"

#define WIFI_TAG "wifi"

//信号量初始化
static SemaphoreHandle_t   s_wifi_connect_sem = NULL;
 char ssid[32] = {0};
 char password[64] = {0};
smartconfig_event_got_ssid_pswd_t *evt = NULL;
void wifi_event_handler(void* event_handler_arg,esp_event_base_t event_base,int32_t event_id,void* event_data)
{
   if(event_base == WIFI_EVENT)
   {
       switch(event_id)
       {
           case WIFI_EVENT_STA_START:
                esp_wifi_connect(); // 连接wifi
                break;
           case WIFI_EVENT_STA_CONNECTED:
                ESP_LOGI(WIFI_TAG,"esp32 connected to ap!");
                xSemaphoreGive(s_wifi_connect_sem); // 连接成功，释放信号量
                break;
            case WIFI_EVENT_STA_DISCONNECTED:
                ESP_LOGI(WIFI_TAG,"esp32 connect fail please retry~~~");
                vTaskDelay(1000 / portTICK_PERIOD_MS); // 1秒后重试
                esp_wifi_connect(); // 重试连接wifi
                break;
            default:
                break;
       }
   }
   else if(event_base == IP_EVENT){
        switch(event_id){
            case IP_EVENT_STA_GOT_IP:
            ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
                ESP_LOGI(WIFI_TAG, "STA Got IP: "IPSTR, IP2STR(&event->ip_info.ip));
                break;
        }
   }
   else if(event_base == SC_EVENT){
       switch(event_id){
           case SC_EVENT_SCAN_DONE:
               ESP_LOGI(WIFI_TAG,"smartconfig scan done");
               break;
            case SC_EVENT_GOT_SSID_PSWD:
            { 
            smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t*)event_data;

            esp_err_t err = write_wifi_info_to_nvs((char *)evt->ssid, (char *)evt->password);
            if (err != ESP_OK) 
            {
                ESP_LOGE(TAG, "Failed to store WiFi credentials: %s", esp_err_to_name(err));
            }
                ESP_LOGI(WIFI_TAG,"SSID:%s",evt->ssid);
                ESP_LOGI(WIFI_TAG,"PASSWORD:%s",evt->password);
                 //data指向空 强转成smartconfig_event_got_ssid_pswd_t指针

                wifi_config_t wifi_config = {0}; //只能配网 wifi_config自己去配
                memset(&wifi_config, 0, sizeof(wifi_config_t)); //清空wifi_config 干干净净的
                //snprintf 就是比sprintf更安全， 不会溢出了，后面的"%s" 表示的就是evt->ssid 的内容

                //这个一键配网就是他自己扫描完了UDP广播包，evt_data里面都有数据了 直接用就可以了
                snprintf((char*)wifi_config.sta.ssid, sizeof(wifi_config.sta.ssid), "%s", (char*)evt->ssid); //将evt->ssid拷贝到wifi_config
                snprintf((char*)wifi_config.sta.password, sizeof(wifi_config.sta.password), "%s", (char*)evt->password); //将evt->password拷贝到wifi_config
                //bssid_set是标识唯一的AP的MAC地址，如果是false，则表示是随机配网，如果是true，则表示是指定AP配网
                //要不然 周围全是不同的SSID 他不知道选哪个了
                wifi_config.sta.bssid_set = evt->bssid_set;
                if(wifi_config.sta.bssid_set){
                    memcpy(wifi_config.sta.bssid, evt->bssid, 6);// MAC地址都是6个字节的
                }
                esp_wifi_disconnect(); //断开当前的wifi连接
                esp_wifi_set_config(WIFI_IF_STA, &wifi_config); //设置新的wifi连接
                esp_wifi_connect(); //连接新的wifi
                xSemaphoreGive(s_wifi_connect_sem); // 连接成功，释放信号量
                break;
            }
            case SC_EVENT_SEND_ACK_DONE: //smartconfig发送ack包完成
            {
                ESP_LOGI(WIFI_TAG,"smartconfig send ack done");
                esp_smartconfig_stop(); //停止smartconfig
                break;
            }
            default:
                break;
       }
   }

}
void wifi_init()
{
        if (nvs_flash_init() == ESP_ERR_NVS_NO_FREE_PAGES || nvs_flash_init() == ESP_ERR_NVS_NEW_VERSION_FOUND)
        {
            ESP_ERROR_CHECK(nvs_flash_init());
        }// 定义好的SSID和PASSWORD都会放在nvs中，所以需要初始化nvs

        // 这个函数是用来清除第一次启动is_first_boot_flag标志的,后续有可能用的上 也就是烧录时候每次就要配网咯
        // ESP_ERROR_CHECK(reset_first_boot_flag());
        
        ESP_ERROR_CHECK(esp_netif_init()); //初始化网络接口
        ESP_ERROR_CHECK(esp_event_loop_create_default());    // 创建默认事件循环并检查是否出错
        esp_netif_create_default_wifi_sta(); // 创建默认的sta模式的wifi接口
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();// 配置wifi初始化参数
        ESP_ERROR_CHECK(esp_wifi_init(&cfg)); //初始化wifi
}
void wifi_smart_normal_config(bool is_first_boot) {
    esp_err_t err = ESP_OK;

    if (is_first_boot) {
        ESP_LOGE(WIFI_TAG, "First boot - SmartConfig");

        // 创建信号量
        if (s_wifi_connect_sem == NULL) {
            s_wifi_connect_sem = xSemaphoreCreateBinary();
        }

        // 注册事件处理函数
        esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);
        esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL);
        esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);

        // 启动 Wi-Fi
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
        ESP_ERROR_CHECK(esp_wifi_start());
        esp_smartconfig_set_type(SC_TYPE_ESPTOUCH);

        smartconfig_start_config_t sc_cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_smartconfig_start(&sc_cfg)); // 启动 SmartConfig

        // 等待 Wi-Fi 连接
        xSemaphoreTake(s_wifi_connect_sem, portMAX_DELAY);
    } else {
        ESP_LOGE(WIFI_TAG, "Normal boot - Using saved Wi-Fi config");
          if (s_wifi_connect_sem == NULL) {
            s_wifi_connect_sem = xSemaphoreCreateBinary();
        }
        esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);
        esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL);
        // 加载已保存的 Wi-Fi 配置
        wifi_load_data(ssid, password);
        if (ssid[0] == '\0' || password[0] == '\0') {
            ESP_LOGE(WIFI_TAG, "Error: SSID or password is empty");
        } else {
            ESP_LOGI(WIFI_TAG, "SSID: %s, Password: %s", ssid, password);
        }
        // 配置 Wi-Fi 并启动
        wifi_config_t wifi_config = {
            .sta.threshold.authmode = WIFI_AUTH_WPA2_PSK,
            .sta.pmf_cfg.capable = true,
            .sta.pmf_cfg.required = false,
        };
        snprintf((char*)wifi_config.sta.ssid, sizeof(wifi_config.sta.ssid), "%s", ssid);
        snprintf((char*)wifi_config.sta.password, sizeof(wifi_config.sta.password), "%s", password);

        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
        ESP_ERROR_CHECK(esp_wifi_start());

        // 等待 Wi-Fi 连接
        xSemaphoreTake(s_wifi_connect_sem, pdMS_TO_TICKS(10000));
    }
}


void wifi_load_data( char *ssid, char *password)//存储配网信息
{
    esp_err_t err =  read_wifi_info_from_nvs(ssid,password);
    if (err != ESP_OK) {
        ESP_LOGE(WIFI_TAG, "Failed to read WiFi data from NVS! Error: %d", err);
    }
    else{
         ESP_LOGI(WIFI_TAG, "Loaded Wi-Fi SSID: %s, Password: %s", ssid, password);
    }
}

